/*******************************************************************************
 * Copyright (c) 2005 - 2013 ACIN, Profactor GmbH, fortiss GmbH
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *   Rene Smodic, Thomas Strasser, Alois Zoitl, Ingo Hegny, Monika Wenger
 *    - initial API and implementation and/or initial documentation
 *******************************************************************************/

#pragma once

namespace forte::util {
  /*!\ingroup FORTE_HAL
   * \brief CDeviceLog is the entity that logs messages created by the FORTE Runtime system.
   * They can be printed to a console or archived somewhere (This is implementation dependent).
   */

  enum class E_MsgLevel { Info, Warning, Error, Debug, Trace };

  // possible loglevels: NOLOG, LOGERROR, LOGWARNING, LOGINFO, LOGDEBUG
  /* Meaning:
   * LOGERROR: log only error messages
   * LOGWARNING: log error and warning messages
   * LOGINFO: log error, warning, and info messages
   * LOGDEBUG: log all messages: error, warning, info, and debug
   * NOLOG: log no messages
   */

#if !(defined(FORTE_NOLOG) || defined(FORTE_LOGERROR) || defined(FORTE_LOGWARNING) || defined(FORTE_LOGINFO) ||        \
      defined(FORTE_LOGDEBUG))
#define FORTE_LOGDEBUG /* Set default loglevel */
#endif

#ifdef FORTE_LOGDEBUG
#define DEVLOG_ERROR(...) ::forte::util::logMessage(::forte::util::E_MsgLevel::Error, __VA_ARGS__)
#define DEVLOG_WARNING(...) ::forte::util::logMessage(::forte::util::E_MsgLevel::Warning, __VA_ARGS__)
#define DEVLOG_INFO(...) ::forte::util::logMessage(::forte::util::E_MsgLevel::Info, __VA_ARGS__)
#define DEVLOG_DEBUG(...) ::forte::util::logMessage(::forte::util::E_MsgLevel::Debug, __VA_ARGS__)
#define DEVLOG_ERROR_VAR(X) X
#define DEVLOG_WARNING_VAR(X) X
#define DEVLOG_INFO_VAR(X) X
#define DEVLOG_DEBUG_VAR(X) X
#endif

#ifdef FORTE_LOGERROR
#define DEVLOG_ERROR(...) ::forte::util::logMessage(::forte::util::E_MsgLevel::Error, __VA_ARGS__)
#define DEVLOG_WARNING(...)
#define DEVLOG_INFO(...)
#define DEVLOG_DEBUG(...)
#define DEVLOG_ERROR_VAR(X) X
#define DEVLOG_WARNING_VAR(X)
#define DEVLOG_INFO_VAR(X)
#define DEVLOG_DEBUG_VAR(X)
#endif

#ifdef FORTE_LOGWARNING
#define DEVLOG_ERROR(...) ::forte::util::logMessage(::forte::util::E_MsgLevel::Error, __VA_ARGS__)
#define DEVLOG_WARNING(...) ::forte::util::logMessage(::forte::util::E_MsgLevel::Warning, __VA_ARGS__)
#define DEVLOG_INFO(...)
#define DEVLOG_DEBUG(...)
#define DEVLOG_ERROR_VAR(X) X
#define DEVLOG_WARNING_VAR(X) X
#define DEVLOG_INFO_VAR(X)
#define DEVLOG_DEBUG_VAR(X)
#endif

#ifdef FORTE_LOGINFO
#define DEVLOG_ERROR(...) ::forte::util::logMessage(::forte::util::E_MsgLevel::Error, __VA_ARGS__)
#define DEVLOG_WARNING(...) ::forte::util::logMessage(::forte::util::E_MsgLevel::Warning, __VA_ARGS__)
#define DEVLOG_INFO(...) ::forte::util::logMessage(::forte::util::E_MsgLevel::Info, __VA_ARGS__)
#define DEVLOG_DEBUG(...)
#define DEVLOG_ERROR_VAR(X) X
#define DEVLOG_WARNING_VAR(X) X
#define DEVLOG_INFO_VAR(X) X
#define DEVLOG_DEBUG_VAR(X)
#endif

#ifdef FORTE_NOLOG
#define DEVLOG_INFO(...)
#define DEVLOG_WARNING(...)
#define DEVLOG_ERROR(...)
#define DEVLOG_DEBUG(...)
#define DEVLOG_ERROR_VAR(X)
#define DEVLOG_WARNING_VAR(X)
#define DEVLOG_INFO_VAR(X)
#define DEVLOG_DEBUG_VAR(X)
#endif

#if (defined(FORTE_TRACE_EVENTS) && !defined(FORTE_NOLOG))
#define FORTE_TRACE(...) ::forte::util::logMessage(::forte::util::E_MsgLevel::Trace, __VA_ARGS__)
#else
#define FORTE_TRACE(...)
#endif

#ifndef FORTE_NOLOG

  /*! \brief Adds an Entry to the LogBook
   *
   */
  void logMessage(E_MsgLevel paLevel, const char *pacMessage, ...);
#endif // #ifndef FORTE_NOLOG
} // namespace forte::util
